import { type Ref, ref, onMounted, onUnmounted, watch } from "vue";
import L, { type Map, type LatLngExpression } from "leaflet";
import "leaflet-animated-marker";
import "leaflet.polylineDecorator";

// 状态机定义 - 播放状态枚举
export type AnimationState =
  | "idle"
  | "playing"
  | "paused"
  | "finished"
  | "error";

// 生命周期回调函数接口
export interface AnimationHooks {
  /** 动画开始前回调 */
  onBeforeStart?: () => void | Promise<void>;
  /** 动画开始后回调 */
  onAfterStart?: () => void | Promise<void>;
  /** 动画暂停前回调 */
  onBeforePause?: () => void | Promise<void>;
  /** 动画暂停后回调 */
  onAfterPause?: () => void | Promise<void>;
  /** 动画停止前回调 */
  onBeforeStop?: () => void | Promise<void>;
  /** 动画停止后回调 */
  onAfterStop?: () => void | Promise<void>;
  /** 动画完成时回调 */
  onComplete?: () => void | Promise<void>;
  /** 动画出错时回调 */
  onError?: (error: Error) => void | Promise<void>;
  /** 动画进度更新时回调 */
  onProgress?: (progress: number) => void | Promise<void>;
}

// 路径动画配置项
export interface RouteAnimationOptions extends AnimationHooks {
  /** 动画更新间隔(ms) */
  interval?: number;
  /** 车辆图标配置 */
  iconOptions?: L.IconOptions;
  /** 轨迹线样式 */
  polylineOptions?: L.PolylineOptions;
  /** 已行驶轨迹线样式 */
  realtimePolylineOptions?: L.PolylineOptions;
}

// 路径点数据类型
export interface RoutePoint {
  /** 纬度 */
  lat: number;
  /** 经度 */
  lng: number;
  /** 该路段速度系数 */
  speed?: number;
}

export function useRouteAnimation(
  map: Map | Ref<Map | null>,
  routePoints: RoutePoint[],
  options: RouteAnimationOptions = {}
) {
  // 状态管理 - 状态机实现
  const state = ref<AnimationState>("idle");
  const animationProgress = ref(0);
  const currentSpeed = ref(1);

  // 内部状态
  const animatedMarker = ref<any>(null);
  const routeLine = ref<L.Polyline | null>(null);
  const realtimeRouteLine = ref<L.Polyline | null>(null);
  const traveledPoints = ref<LatLngExpression[]>([]);
  const animationTimer = ref<NodeJS.Timeout | null>(null);

  // 默认配置
  const defaultOptions: Required<
    Omit<RouteAnimationOptions, keyof AnimationHooks>
  > = {
    interval: 200,
    iconOptions: {
      iconSize: [37, 26],
      iconAnchor: [19, 13],
      iconUrl: "/src/assets/car.png"
    },
    polylineOptions: {
      weight: 8,
      color: "#3388ff"
    },
    realtimePolylineOptions: {
      weight: 8,
      color: "#FF9900"
    }
  };

  // 合并配置
  const mergedOptions = { ...defaultOptions, ...options };

  // 状态转换表 - 定义合法的状态转换
  const stateTransitions: Record<AnimationState, AnimationState[]> = {
    idle: ["playing", "error"],
    playing: ["paused", "finished", "error", "idle"],
    paused: ["playing", "idle", "error"],
    finished: ["playing", "idle", "error"],
    error: ["idle"]
  };

  // 状态转换方法
  const transitionState = async (newState: AnimationState, error?: Error) => {
    const currentState = state.value;

    // 检查状态转换是否合法
    if (!stateTransitions[currentState].includes(newState)) {
      const err = new Error(`不允许从 ${currentState} 转换到 ${newState}`);
      options.onError?.(err);
      state.value = "error";
      return;
    }

    // 触发状态变更前回调
    const beforeCallback =
      options[`onBefore${capitalize(newState)}` as keyof AnimationHooks];
    if (beforeCallback && typeof beforeCallback === "function") {
      try {
        await beforeCallback();
      } catch (err) {
        options.onError?.(err as Error);
        state.value = "error";
        return;
      }
    }

    // 执行状态变更
    state.value = newState;

    // 触发状态变更后回调
    const afterCallback =
      options[`onAfter${capitalize(newState)}` as keyof AnimationHooks];
    if (afterCallback && typeof afterCallback === "function") {
      try {
        await afterCallback();
      } catch (err) {
        options.onError?.(err as Error);
        state.value = "error";
      }
    }

    // 特殊状态处理
    if (newState === "error" && error) {
      options.onError?.(error);
    } else if (newState === "finished") {
      options.onComplete?.();
    }
  };

  // 辅助函数：首字母大写
  function capitalize(str: string): string {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }

  // 初始化路径动画
  const init = () => {
    if (isRef(map) && !map.value) return;
    const mapInstance = isRef(map) ? map.value! : map;

    try {
      // 提取经纬度坐标
      const latlngs = routePoints.map(
        point => [point.lat, point.lng] as LatLngExpression
      );
      // 提取速度数组
      const speedList = routePoints.map(point => point.speed || 1);

      // 创建完整路线轨迹线
      routeLine.value = L.polyline(
        latlngs,
        mergedOptions.polylineOptions
      ).addTo(mapInstance);

      // 创建已行驶轨迹线
      realtimeRouteLine.value = L.polyline(
        [],
        mergedOptions.realtimePolylineOptions
      ).addTo(mapInstance);

      // 添加方向箭头
      addDirectionArrows(mapInstance);

      // 创建车辆标记
      createAnimatedMarker(mapInstance, latlngs, speedList);

      // 自动适应地图视角以显示完整路线
      mapInstance.fitBounds(routeLine.value.getBounds(), { padding: [50, 50] });
    } catch (error) {
      transitionState("error", error as Error);
    }
  };

  // 添加轨迹方向箭头
  const addDirectionArrows = (mapInstance: Map) => {
    if (!routeLine.value) return;

    L.polylineDecorator(routeLine.value, {
      patterns: [
        {
          repeat: 50,
          symbol: L.Symbol.arrowHead({
            pixelSize: 15,
            headAngle: 60,
            pathOptions: {
              color: "#ffffff",
              weight: 2,
              opacity: 0.8
            }
          })
        }
      ]
    }).addTo(mapInstance);
  };

  // 创建动态标记(车辆)
  const createAnimatedMarker = (
    mapInstance: Map,
    latlngs: LatLngExpression[],
    speedList: number[]
  ) => {
    const carIcon = L.icon(mergedOptions.iconOptions);

    // 使用animated-marker插件创建动态标记
    animatedMarker.value = L.animatedMarker(latlngs, {
      icon: carIcon,
      speedList: speedList,
      interval: mergedOptions.interval,
      playCall: updateTraveledRoute,
      onEnd: () => transitionState("finished")
    }).addTo(mapInstance);

    // 初始添加起点
    traveledPoints.value.push(latlngs[0]);
  };

  // 更新已行驶轨迹
  const updateTraveledRoute = (latlng: LatLngExpression) => {
    traveledPoints.value.push(latlng);
    realtimeRouteLine.value?.setLatLngs(traveledPoints.value);

    // 更新进度
    const totalPoints = routePoints.length;
    const progress = Math.round(
      (traveledPoints.value.length / totalPoints) * 100
    );
    animationProgress.value = progress;
    options.onProgress?.(progress);
  };

  // 动画控制方法
  const start = async () => {
    if (!animatedMarker.value || state.value === "playing") return;

    try {
      animatedMarker.value.start();
      await transitionState("playing");
    } catch (error) {
      transitionState("error", error as Error);
    }
  };

  const pause = async () => {
    if (!animatedMarker.value || state.value !== "playing") return;

    try {
      animatedMarker.value.pause();
      await transitionState("paused");
    } catch (error) {
      transitionState("error", error as Error);
    }
  };

  const stop = async () => {
    if (!animatedMarker.value || ["idle", "finished"].includes(state.value))
      return;

    try {
      animatedMarker.value.stop();
      traveledPoints.value = [traveledPoints.value[0]];
      realtimeRouteLine.value?.setLatLngs(traveledPoints.value);
      animationProgress.value = 0;
      await transitionState("idle");
    } catch (error) {
      transitionState("error", error as Error);
    }
  };

  const speedUp = () => {
    if (!animatedMarker.value) return;
    currentSpeed.value *= 2;
    animatedMarker.value.setSpeedX(currentSpeed.value); // 修复拼写错误: speetX -> speedX
  };

  const speedDown = () => {
    if (!animatedMarker.value) return;
    currentSpeed.value /= 2;
    animatedMarker.value.setSpeedX(currentSpeed.value); // 修复拼写错误: speetX -> speedX
  };

  // 清理方法
  const destroy = () => {
    if (animationTimer.value) {
      clearInterval(animationTimer.value);
    }
    if (animatedMarker.value) {
      animatedMarker.value.stop();
      animatedMarker.value.remove();
    }
    routeLine.value?.remove();
    realtimeRouteLine.value?.remove();
    traveledPoints.value = [];
  };

  // 框架生命周期钩子 - 初始化
  onMounted(() => {
    if (!isRef(map) || map.value) {
      init();
    } else {
      // 如果map是ref且尚未初始化，等待其变化
      const unwatch = watch(map, newMap => {
        if (newMap) {
          init();
          unwatch();
        }
      });
    }
  });

  // 框架生命周期钩子 - 清理
  onUnmounted(() => {
    destroy();
  });

  return {
    // 状态数据
    state,
    animationProgress,
    currentSpeed,

    // 控制方法
    controls: {
      init,
      start,
      pause,
      stop,
      speedUp,
      speedDown,
      destroy
    }
  };
}
